package concurrent.completableFuture;

import com.alibaba.fastjson.JSON;
import org.junit.Test;

import java.util.concurrent.*;

/**
 * @author LoneRanger
 * @version 1.0
 */
public class FutureJava5Test {

	/**
	 * 无异步任务情况下，多个任务会串行执行，用时较长
	 */
	@Test
	public void testNoFuture() {

		long startTime = System.currentTimeMillis();

		UserService userService = new UserService();
		MedalService medalService = new MedalService();

		UserInfo userInfo = userService.getUserInfo(1);
		MedalInfo medalInfo = medalService.getMedalInfo(1);

		try {
			//模拟主线程运行
			TimeUnit.SECONDS.sleep(5);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("user:" + JSON.toJSONString(userInfo));
		System.out.println("medal:" + JSON.toJSONString(medalInfo));
		System.out.println("用时：" + (System.currentTimeMillis() - startTime));
	}

	/**
	 * 创建异步任务
	 * 使用Future + 线程池的异步配合，可以极大的提高执行效率
	 * 但是对于结果的获取，并不友好，只能通过阻塞或者轮训的方式得到任务的结果
	 * <p>
	 * Future.get() 就是阻塞调用，在线程获取结果之前get方法会一直阻塞。
	 * Future提供了一个isDone方法，可以在程序中轮询这个方法查询执行结果。
	 * <p>
	 * 阻塞的方式和异步编程的设计理念相违背，而轮询的方式会耗费无谓的CPU资源。
	 */
	@Test
	public void testHaveFuture() throws ExecutionException, InterruptedException {
		long startTime = System.currentTimeMillis();
		ExecutorService executorService = Executors.newFixedThreadPool(10);

		UserService userService = new UserService();
		MedalService medalService = new MedalService();

		FutureTask<UserInfo> userInfoFutureTask =
				new FutureTask<>(() -> userService.getUserInfo(1));
		executorService.submit(userInfoFutureTask);

		FutureTask<MedalInfo> medalInfoFutureTask =
				new FutureTask<>(() -> medalService.getMedalInfo(1));

		executorService.submit(medalInfoFutureTask);

		try {
			//模拟主线程运行
			TimeUnit.SECONDS.sleep(5);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("user:" + JSON.toJSONString(userInfoFutureTask.get()));
		System.out.println("medal:" + JSON.toJSONString(medalInfoFutureTask.get()));
		System.out.println("用时：" + (System.currentTimeMillis() - startTime));

	}
}

